package com.ruoyi.common.utils.bean;


import org.apache.commons.lang3.StringUtils;
import org.springframework.cglib.beans.BeanMap;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 获取对象属性信息 总结 结语 详细
 *
 * @author Dhe
 */
public class BeanFiledUtil {


    /**
     * 根据属性名获取属性值
     */
    public static boolean checkFieldExit(String fieldName, Object o) {
        try {
            char[] items = ("get" + fieldName).toCharArray();
            items[3] = Character.toUpperCase(items[3]);
            Method method = o.getClass().getMethod(new String(items), new Class[]{});
            method.invoke(o, new Object[]{});
        } catch (NoSuchMethodException e) {
            return false;
        } catch (IllegalAccessException e) {
            return false;
        } catch (InvocationTargetException e) {
            return false;
        } catch (Exception e) {
            return false;
        }
        return true;

    }

    /**
     * 根据属性名获取属性值
     */
    public static Object getFieldValueByName(String fieldName, Object o) {

        Object value = null;
        try {
            char[] items = ("get" + fieldName).toCharArray();
            items[3] = Character.toUpperCase(items[3]);
            Method method = o.getClass().getMethod(new String(items), new Class[]{});
            value = method.invoke(o, new Object[]{});
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return value;

    }

    /**
     * 通过属性名得到属性值
     *
     * @param object   对象
     * @param property 属性名
     * @return 值
     */
    public static Object getFieldValue(Object object, String property) {
        return BeanMap.create(object).get(property);
    }

    /**
     * 给bean属性赋值
     *
     * @param object   对象
     * @param property 属性名
     * @param value    值
     */
    public static void setFieldValue(Object object, Object property, Object value) {
        try {
            BeanMap.create(object).put(property, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取属性名数组
     */
    public static String[] getFiledName(Object o) {
        Field[] fields = o.getClass().getDeclaredFields();
        String[] fieldNames = new String[fields.length];
        for (int i = 0; i < fields.length; i++) {
            fieldNames[i] = fields[i].getName();
        }
        return fieldNames;
    }

    /**
     * 获取属性类型(type)，属性名(name)，属性值(value)的map组成的list
     */
    public static List getFiledsInfo(Object o) {
        Field[] fields = o.getClass().getDeclaredFields();

        List list = new ArrayList();
        Map infoMap = null;
        for (int i = 0; i < fields.length; i++) {
            infoMap = new HashMap(16);
            infoMap.put("type", fields[i].getType().toString());
            infoMap.put("name", fields[i].getName());
            infoMap.put("value", getFieldValueByName(fields[i].getName(), o));
            list.add(infoMap);
        }
        return list;
    }

    /**
     * 获取对象的所有属性值，返回一个对象数组
     */
    public static Object[] getFiledValues(Object o) {
        String[] fieldNames = getFiledName(o);
        Object[] value = new Object[fieldNames.length];
        for (int i = 0; i < fieldNames.length; i++) {
            value[i] = getFieldValueByName(fieldNames[i], o);
        }
        return value;
    }

    /**
     * 获取对象的所有属性值，返回一个对象数组
     */
    public static List<String> getClassFiledList(Object o) {
        List<String> fileds = new ArrayList<>(16);
        try {
            BeanInfo bi = Introspector.getBeanInfo(o.getClass());
            PropertyDescriptor[] pds = bi.getPropertyDescriptors();
            for (int i = 0; i < pds.length; i++) {
                String propName = pds[i].getName();
                if (!"class".equals(propName)) {
                    fileds.add(propName);
                }
            }
            return fileds;
        } catch (Exception e) {
            e.printStackTrace();
            return fileds;
        }
    }


    public static List<Map<String, Object>> getFiledBeanList(List list, List<String> fields) {
        List<Map<String, Object>> reList = new ArrayList<>(16);
        if (list != null && list.size() > 0) {
            return reList;
        }
        for (Object t : list) {
            Map<String, Object> mm = new HashMap<>(16);
            for (String fi : fields) {
                if (StringUtils.isBlank(fi)) {
                    continue;
                }
                Object fieldValueByName = BeanFiledUtil.getFieldValueByName(fi, t);
                mm.put(fi, fieldValueByName);
            }
            reList.add(mm);
        }
        return reList;
    }

    public static Map<String, Object> getFiledBean(Object o, List<String> fields) {
        Map<String, Object> mm = new HashMap<>(16);
        if (o == null) {
            return mm;
        }
        for (String fi : fields) {
            mm.put(fi, BeanFiledUtil.getFieldValueByName(fi, o));
        }
        return mm;
    }
}
